package com.jiepos.mpos.inter.intopieces.service;

import java.sql.Timestamp;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.jiepos.mpos.biz.code.service.AppAreaCdService;
import com.jiepos.mpos.biz.code.service.InfCnapsService;
import com.jiepos.mpos.biz.code.service.SuperBankService;
import com.jiepos.mpos.biz.customer.service.AppCustomerInfoService;
import com.jiepos.mpos.biz.customer.service.CustomBankcardInfoService;
import com.jiepos.mpos.biz.outservice.service.ServiceInterMchntService;
import com.jiepos.mpos.biz.user.service.AppInsInfService;
import com.jiepos.mpos.common.constant.ExceptionConstant;
import com.jiepos.mpos.common.constant.SystemConstant;
import com.jiepos.mpos.common.entity.App_Custom_BankcardEntity;
import com.jiepos.mpos.common.entity.App_Custom_InfEntity;
import com.jiepos.mpos.common.entity.App_Inf_CnapsEntity;
import com.jiepos.mpos.common.entity.App_Inf_SuperbankEntity;
import com.jiepos.mpos.common.entity.App_Ins_InfEntity;
import com.jiepos.mpos.common.entity.App_Service_Inter_MchntEntity;
import com.jiepos.mpos.common.service.AbrBaseHttpService;
import com.jiepos.mpos.core.entity.MposResponse;
import com.jiepos.mpos.core.exception.MposException;
import com.jiepos.mpos.core.util.DateUtil;
import com.jiepos.mpos.core.util.StringUtils;
import com.jiepos.mpos.inter.fourelement.service.IFourElementService;
import com.jiepos.mpos.inter.intopieces.entity.DebitCardEntity;
import com.jiepos.mpos.inter.intopieces.entity.RegisterEntity;
import com.jiepos.mpos.inter.intopieces.entity.UploadEntity;
import com.jiepos.mpos.inter.intopieces.utils.FieldFilterUtils;
import com.jiepos.mpos.inter.intopieces.utils.FinalDataUtils;

/**
 * @ClassName: MchntIntoPieces
 * @Description: 对外渠道进件管理类
 * @author 孙永
 * @date 2018年3月6日 下午4:59:07
 */
@Service
public class MchntIntoPieces extends AbrBaseHttpService{
	
	@Autowired
	private AppCustomerInfoService customerInfoService;
	@Autowired
	private AppAreaCdService appAreaCdService;
	@Autowired
	private IFourElementService iFourElementService;
	@Autowired
	private ServiceInterMchntService serviceInterMchntService;
	@Autowired
	private AppInsInfService insInfService;
	@Autowired
	private CustomBankcardInfoService bankCardInfoService;
	@Autowired
	private SuperBankService superBankService;
	@Autowired
	private InfCnapsService infCnapsService;
	
	/**
	 * 商户注册服务
	 * @param requestDto
	 * @param bizContent
	 * @return
	 * @throws Exception
	 */
	public Map<String, String> register(Map<String, String> bizContent) throws Exception{
		/*业务参数转实体对象*/
		JSON json = JSONObject.parseObject(JSONObject.toJSONString(bizContent));
		RegisterEntity register = JSONObject.toJavaObject(json, RegisterEntity.class);
		/*商户信息校验*/
		checkRegisterBizContent(register);
		/*基本信息数据入库*/
		App_Custom_InfEntity customer = addCustomer(register, bizContent);
		/*结算卡信息数据入库*/
		addBankCard(register, customer.getCustom_uuid());
		/*建立关联关系*/
		App_Service_Inter_MchntEntity interMchnt = addInterMchnt(register, customer.getCustom_no(), bizContent);
		return registerResp(customer, interMchnt);
	}
	
	/**
	 * 变更结算卡
	 * @param bizContent
	 * @return
	 * @throws Exception 
	 */
	public Map<String, String> debitCard(Map<String, String> bizContent) throws Exception{
		/*业务参数转实体对象*/
		JSON json = JSONObject.parseObject(JSONObject.toJSONString(bizContent));
		DebitCardEntity debitCard = JSONObject.toJavaObject(json, DebitCardEntity.class);
		/*结算卡信息校验*/
		App_Custom_BankcardEntity bankCard = checkDebitCardBizContent(debitCard);
		/*更新结算卡*/
		changeBankCard(bankCard, debitCard);
		return null;
	}
	
	/**
	 * 查询商户信息
	 * @param bizContent
	 * @return
	 */
	public Map<String, String> search(Map<String, String> bizContent){
		App_Service_Inter_MchntEntity interMchnt = null;
		/*判断商户号(会员编号)和外部商户号*/
		if(StringUtils.isNotBlank(bizContent.get("mchnt_cd"))){
			interMchnt = serviceInterMchntService.findByMchntCd(bizContent.get("mchnt_cd"));
		}else if(StringUtils.isNotBlank(bizContent.get("out_mchnt_cd"))){
			interMchnt = serviceInterMchntService.findByServiceMchntCd(bizContent.get("out_mchnt_cd"));
		}else{
			throw new MposException(ExceptionConstant.MER_BIZ_DATA_NULL);
		}
		/*关联关系不存在*/
		if(interMchnt == null){
			throw new MposException(ExceptionConstant.MER_NOT_EXISTS);
		}
		/*根据会员编号查询会员信息*/
		App_Custom_InfEntity customer = customerInfoService.getCustomByNo(interMchnt.getMchnt_cd());
		if(customer == null || StringUtils.isBlank(customer.getCustom_uuid())){
			throw new MposException(ExceptionConstant.MER_NOT_EXISTS);
		}
		/*查询会员结算卡信息*/
		App_Custom_BankcardEntity bankCard = bankCardInfoService.getBankcardEntity(customer.getCustom_uuid(), SystemConstant.ACCT_ATTR_0);
		return searchResp(customer, bankCard, interMchnt);
	}
	
	/**
	 * 上送商户证件信息
	 * @param request
	 * @param response
	 * @param bizContent
	 * @param file
	 * @return
	 * @throws Exception
	 */
	public Map<String, String> upload(HttpServletRequest request, HttpServletResponse response, Map<String, String> bizContent, MultipartFile file) throws Exception{
		/*业务参数转实体对象*/
		JSON json = JSONObject.parseObject(JSONObject.toJSONString(bizContent));
		UploadEntity upload = JSONObject.toJavaObject(json, UploadEntity.class);
		/*图片信息校验*/
		App_Custom_InfEntity customer = checkUpload(upload, file);
		/*图片数据入库*/
		String imgId = addImg(request, response, upload, file, customer);
		return uploadResp(imgId);
	}
	
	/**
	 * 校验商户注册信息
	 * @param register
	 * @throws Exception
	 */
	private void checkRegisterBizContent(RegisterEntity register) throws Exception{
		/*参数基本校验*/
		FieldFilterUtils.fieldFilter(RegisterEntity.class, register);
		/*校验区域编码*/
		Map<String, Object> area = appAreaCdService.getSupAreaByCode(register.getMchnt_area());
		if(area == null || area.isEmpty() || !"3".equals(String.valueOf(area.get("LEVEL_NO")))){
			throw new MposException(ExceptionConstant.MER_AREA_ERROR);
		}
		/*验证结算卡*/
		checkDebitCard(register.getBank_city(), register.getBank_province(), register.getDebit_card_name(), register.getDebit_card_phone(), register.getDebit_card_idcard(),
				register.getDebit_card_no(), register.getBank_no(), register.getBank_branch_no());
		/*查询商户是否已经存在*/
		App_Custom_InfEntity customer = customerInfoService.getCustomInfByPhone(register.getMchnt_phone());
		if(customer != null){
			throw new MposException(ExceptionConstant.MER_EXISTS);
		}
		/*查询中间表验证是否已经存在*/
		App_Service_Inter_MchntEntity mchnt = serviceInterMchntService.findByServiceMchntCd(register.getOut_mchnt_cd());
		if(mchnt != null){
			throw new MposException(ExceptionConstant.MER_EXISTS);
		}
	}
	
	/**
	 * 校验商户变更结算卡信息
	 * @param debitCard
	 * @throws Exception
	 */
	private App_Custom_BankcardEntity checkDebitCardBizContent(DebitCardEntity debitCard) throws Exception{
		/*参数基本校验*/
		FieldFilterUtils.fieldFilter(DebitCardEntity.class, debitCard);
		/*验证结算卡*/
		checkDebitCard(debitCard.getBank_city(), debitCard.getBank_province(), debitCard.getDebit_card_name(), debitCard.getDebit_card_phone(), debitCard.getDebit_card_idcard(),
				debitCard.getDebit_card_no(), debitCard.getBank_no(), debitCard.getBank_branch_no());
		/*查询商户是否存在*/
		App_Service_Inter_MchntEntity interMchnt = serviceInterMchntService.findByMchntCd(debitCard.getMchnt_cd());
		if(interMchnt == null){
			throw new MposException(ExceptionConstant.MER_NOT_EXISTS);
		}
		App_Custom_InfEntity customer = customerInfoService.getCustomByNo(debitCard.getMchnt_cd());
		if(customer == null || StringUtils.isBlank(customer.getCustom_uuid())){
			throw new MposException(ExceptionConstant.MER_NOT_EXISTS);
		}
		/*查询已绑定的结算卡*/
		App_Custom_BankcardEntity bankCard = bankCardInfoService.getBankcardEntity(customer.getCustom_uuid(), SystemConstant.ACCT_ATTR_0);
		if(bankCard == null){
			throw new MposException(ExceptionConstant.MER_BANK_NOT_BIND);
		}
		return bankCard;
	}
	
	/**
	 * 验证结算卡
	 * @param bankCity 开户城市
	 * @param bankProvince 开户省份
	 * @param name 账户名
	 * @param phone 预留手机号
	 * @param idCard 身份证号
	 * @param bankCardNo 账号
	 */
	private void checkDebitCard(String bankCity, String bankProvince, String name, String phone, String idCard, String bankCardNo, String superNo, String branchNo){
		/*校验开户省市编码*/
		Map<String, Object> bankArea = appAreaCdService.getSupAreaByCode(bankCity);
		if(bankArea == null || bankArea.isEmpty() || !"2".equals(String.valueOf(bankArea.get("LEVEL_NO")))){//开户城市不支持
			throw new MposException(ExceptionConstant.MER_BANK_CITY_ERROR);
		}else if(!bankProvince.equals(String.valueOf(bankArea.get("SUP_AREA_CD")))){//开户省份不支持
			throw new MposException(ExceptionConstant.MER_BANK_PROVINCE_ERROR);
		}
		/*校验总行*/
		App_Inf_SuperbankEntity superBank = superBankService.getSuperBankByNo(superNo);
		if(superBank == null || StringUtils.isBlank(superBank.getSuper_bank_uuid())){
			throw new MposException(ExceptionConstant.MER_BANK_SUPER_NOT_BIND);
		}
		/*校验分行*/
		App_Inf_CnapsEntity branchBank = infCnapsService.getCnapsByNo(branchNo);
		if(branchBank == null || StringUtils.isBlank(branchBank.getCnaps_uuid())){
			throw new MposException(ExceptionConstant.MER_BANK_BRANCH_NOT_BIND);
		}
		/*总行与支行不匹配*/
		if(!superNo.equals(branchBank.getSuper_bank_no())){
			throw new MposException(ExceptionConstant.MER_BANK_NOT_MATCHING);
		}
		/*四要素验证*/
//		Map<String, String> result = iFourElementService.queryFourElement(new FourElements(name, phone, idCard, bankCardNo), new HashMap<>());
//		if(result == null || !SystemConstant.RSPCODE_SUCCESS.equals(result.get(SystemConstant.RSP_CODE))){
//			throw new MposException(ExceptionConstant.MER_BANK_FOUR_FAIL);
//		}
	}
	
	private App_Custom_InfEntity checkUpload(UploadEntity upload, MultipartFile file) throws Exception{
		/*参数基本校验*/
		FieldFilterUtils.fieldFilter(UploadEntity.class, upload);
		/*文件校验*/
		if(file == null){
			throw new MposException(ExceptionConstant.MER_IMG_UPLOAD_NULL);
		}
		/*验证证件类型是否合格*/
		if(!FinalDataUtils.IMG_TYPE.contains(upload.getImg_type())){
			throw new MposException(ExceptionConstant.MER_IMG_TYPE_ERROR);
		}
		String fileName = file.getOriginalFilename();
		String fileSuffix = fileName.substring(fileName.lastIndexOf(".") + 1);
		/*验证文件格式是否符合要求*/
		if(!FinalDataUtils.IMG_SUFFIX.contains(fileSuffix.toLowerCase())){
			throw new MposException(ExceptionConstant.MER_IMG_FORMAT_ERROR);
		}
		/*验证文件大小是否超出最大限制*/
		if(file.getSize() > FinalDataUtils.IMG_MAX_SIZE){
			throw new MposException(ExceptionConstant.MER_IMG_SIZE_TOO_BIG);
		}
		/*查询商户是否存在*/
		App_Service_Inter_MchntEntity interMchnt = serviceInterMchntService.findByMchntCd(upload.getMchnt_cd());
		if(interMchnt == null){
			throw new MposException(ExceptionConstant.MER_NOT_EXISTS);
		}
		App_Custom_InfEntity customer = customerInfoService.getCustomByNo(upload.getMchnt_cd());
		if(customer == null || StringUtils.isBlank(customer.getCustom_uuid())){
			throw new MposException(ExceptionConstant.MER_NOT_EXISTS);
		}
		return customer;
	}
	
	/**
	 * 创建会员
	 * @param register
	 * @return 返回会员编号
	 * @throws Exception 
	 */
	private App_Custom_InfEntity addCustomer(RegisterEntity register, Map<String, String> params) throws Exception{
		String pwd = register.getMchnt_idcard().substring(14).toUpperCase();
		/*获取父级*/
		App_Ins_InfEntity inf = insInfService.getInsInfByUuid(params.get(FinalDataUtils.INS_UUID));
		App_Custom_InfEntity superCustomer = customerInfoService.getCustomInfByPhone(inf.getPhone());
		if(superCustomer == null){
			
		}
		App_Custom_InfEntity customer = new App_Custom_InfEntity();
		customer.setAddr(register.getMchnt_address()); // 地址
		customer.setCertificate_no(register.getMchnt_idcard()); // 身份证号
		customer.setIns_uuid(params.get(FinalDataUtils.INS_UUID)); // 所属APP机构
		customer.setLogin_id(register.getMchnt_phone()); // 登录账号
		customer.setName(register.getMchnt_name()); // 姓名
		customer.setPhone(register.getMchnt_phone()); // 联系方式
		customer.setSup_custom_uuid(superCustomer.getCustom_uuid()); // 父级
		customer.setPass_word(pwd); // 登录密码
		customer.setPay_pass_word(pwd); // 支付密码
		customer.setRealname_auth_st(SystemConstant.AUTH_ST_1); // 实名状态
		customer.setRealname_audit_st(SystemConstant.REVIEW_ST_1); // 审核状态
		customer.setRealname_auth_ts(new Timestamp(System.currentTimeMillis())); // 实名认证时间
		customer.setRec_upd_usr_id(register.getMchnt_phone());
		return customerInfoService.saveCustomer(customer);
	}
	
	/**
	 * 生成结算卡数据
	 * @param register
	 * @param customUuid 会员唯一标识
	 */
	private void addBankCard(RegisterEntity register, String customUuid){
		/*获取总行和支行信息*/
		App_Inf_CnapsEntity branchBank = infCnapsService.getCnapsByNo(register.getBank_branch_no());
		App_Inf_SuperbankEntity superBank = superBankService.getSuperBankByNo(register.getBank_no());
		
		/*获取结算卡是否已经存在，存在则更新，防止出现多条记录*/
		App_Custom_BankcardEntity bankCard = new App_Custom_BankcardEntity();
		bankCard.setCustom_uuid(customUuid);
		bankCard.setSuper_bank_no(register.getBank_no()); // 总行号
		bankCard.setSuper_bank_nm(superBank.getBank_nm()); // 总行名称
		bankCard.setSettle_bank_no(register.getBank_branch_no()); // 支行号
		bankCard.setBank_nm(branchBank.getBank_nm()); // 支行名称
		bankCard.setSettle_acct(register.getDebit_card_no()); // 账号
		bankCard.setAcct_nm(register.getDebit_card_name()); // 账户名称
		bankCard.setBank_province(register.getBank_province()); // 开户省份
		bankCard.setBank_locality(register.getBank_city()); // 开户地市
		bankCard.setPhone(register.getDebit_card_phone()); // 预留手机号
		bankCard.setCertificate_no(register.getDebit_card_idcard()); // 身份证号
		bankCard.setAcct_attr(SystemConstant.ACCT_ATTR_0); // 借记卡
		bankCard.setAudit_st(SystemConstant.REVIEW_ST_1); // 审核通过
		
		Map<String, String> map = new HashMap<>();
        map.put(SystemConstant.SESSION_LOGIN_USER, register.getMchnt_phone());
        
        bankCardInfoService.saveCustomBankcard(bankCard, map);
	}
	
	/**
	 * 更新结算卡
	 * @param bankCard
	 * @param debitCard
	 */
	private void changeBankCard(App_Custom_BankcardEntity bankCard, DebitCardEntity debitCard){
		/*获取总行和支行信息*/
		App_Inf_CnapsEntity branchBank = infCnapsService.getCnapsByNo(debitCard.getBank_branch_no());
		App_Inf_SuperbankEntity superBank = superBankService.getSuperBankByNo(debitCard.getBank_no());
		
		bankCard.setSuper_bank_no(debitCard.getBank_no()); // 总行号
		bankCard.setSuper_bank_nm(superBank.getBank_nm()); // 总行名称
		bankCard.setSettle_bank_no(debitCard.getBank_branch_no()); // 支行号
		bankCard.setBank_nm(branchBank.getBank_nm()); // 支行名称
		bankCard.setSettle_acct(debitCard.getDebit_card_no()); // 账号
		bankCard.setAcct_nm(debitCard.getDebit_card_name()); // 账户名称
		bankCard.setBank_province(debitCard.getBank_province()); // 开户省份
		bankCard.setBank_locality(debitCard.getBank_city()); // 开户地市
		bankCard.setPhone(debitCard.getDebit_card_phone()); // 预留手机号
		bankCard.setCertificate_no(debitCard.getDebit_card_idcard()); // 身份证号
		
		Map<String, String> map = new HashMap<>();
        map.put(SystemConstant.SESSION_LOGIN_USER, debitCard.getDebit_card_phone());
        
        bankCardInfoService.saveCustomBankcard(bankCard, map);
	}
	
	/**
	 * 保存关联关系
	 * @param register
	 * @param customerNo
	 * @param params
	 */
	private App_Service_Inter_MchntEntity addInterMchnt(RegisterEntity register, String customerNo, Map<String, String> params){
		App_Service_Inter_MchntEntity interMchnt = new App_Service_Inter_MchntEntity();
		interMchnt.setMchnt_cd(customerNo);
		interMchnt.setMchnt_nm(register.getMchnt_name());
		interMchnt.setMchnt_short_nm(register.getMchnt_short_name());
		interMchnt.setRec_upd_usr_id(register.getMchnt_phone());
		interMchnt.setService_mchnt_cd(register.getOut_mchnt_cd());
		interMchnt.setIns_uuid(params.get(FinalDataUtils.INS_UUID));
		interMchnt.setTerm_id(getTermId());
		return serviceInterMchntService.save(interMchnt);
	}
	
	private String addImg(HttpServletRequest req, HttpServletResponse res, UploadEntity upload, MultipartFile file, App_Custom_InfEntity customer){
		MposResponse affix = null;
		switch(upload.getImg_type()){
		case FinalDataUtils.IMG_TYPE_1 :
			affix = uploadImgForApp(req, res, file, customer.getCustom_uuid(), SystemConstant.AFFIX_TP_01, SystemConstant.STORE_TP_01_04, customer.getName(), customer.getCustom_no());
			break;
		case FinalDataUtils.IMG_TYPE_2 :
			affix = uploadImgForApp(req, res, file, customer.getCustom_uuid(), SystemConstant.AFFIX_TP_01, SystemConstant.STORE_TP_01_05, customer.getName(), customer.getCustom_no());
			break;
		case FinalDataUtils.IMG_TYPE_3 :
			affix = uploadImgForApp(req, res, file, customer.getCustom_uuid(), SystemConstant.AFFIX_TP_02, SystemConstant.STORE_TP_02_01, customer.getName(), customer.getCustom_no());
			break;
		case FinalDataUtils.IMG_TYPE_4 :
			affix = uploadImgForApp(req, res, file, customer.getCustom_uuid(), SystemConstant.AFFIX_TP_02, SystemConstant.STORE_TP_02_02, customer.getName(), customer.getCustom_no());
			break;
		case FinalDataUtils.IMG_TYPE_5 :
			affix = uploadImgForApp(req, res, file, customer.getCustom_uuid(), SystemConstant.AFFIX_TP_02, SystemConstant.STORE_TP_02_03, customer.getName(), customer.getCustom_no());
			break;
		}
		if(affix == null){
			throw new MposException(ExceptionConstant.MER_IMG_UPLOAD_FAIL);
		}
		return String.valueOf(affix.getRespData());
	}

	/**
	 * 生成终端号
	 * @return
	 */
	private String getTermId(){
		String termId = String.valueOf(System.currentTimeMillis());
		return termId.substring(5);
	}
	
	/**
	 * 格式化时间
	 * @param time
	 * @return
	 */
	private String formatTime(Timestamp time){
		return DateUtil.dateToStr(new Date(time.getTime()), "yyyyMMddHHmmss");
	}
	
	/**
	 * 组装注册业务应答参数报文
	 * @param customer
	 * @param interMchnt
	 * @return
	 */
	private Map<String, String> registerResp(App_Custom_InfEntity customer, App_Service_Inter_MchntEntity interMchnt){
		Map<String, String> map = new HashMap<>();
		map.put("mchnt_cd", customer.getCustom_no());
		map.put("review_status", customer.getRealname_audit_st());
		map.put("register_time", formatTime(customer.getRec_crt_ts()));
		map.put("term_id", interMchnt.getTerm_id());
		return map;
	}
	
	/**
	 * 组装查询业务应答参数报文
	 * @param customer
	 * @param bankCard
	 * @param interMchnt
	 * @return
	 */
	private Map<String, String> searchResp(App_Custom_InfEntity customer, App_Custom_BankcardEntity bankCard, App_Service_Inter_MchntEntity interMchnt){
		Map<String, String> map = new HashMap<>();
		map.put("mchnt_cd", interMchnt.getMchnt_cd());
		map.put("out_mchnt_cd", interMchnt.getService_mchnt_cd());
		map.put("mchnt_short_name", interMchnt.getMchnt_short_nm());
		map.put("mchnt_name", customer.getName());
		map.put("mchnt_phone", customer.getPhone());
		map.put("mchnt_idcard", customer.getCertificate_no());
		map.put("mchnt_address", customer.getAddr());
		map.put("review_status", customer.getRealname_audit_st());
		map.put("review_time", formatTime(customer.getRealname_auth_ts()));
		map.put("register_time", formatTime(customer.getRec_crt_ts()));
		map.put("bank_province", bankCard.getBank_province());
		map.put("bank_city", bankCard.getBank_locality());
		map.put("bank_no", bankCard.getSuper_bank_no());
		map.put("bank_branch_no", bankCard.getSettle_bank_no());
		map.put("debit_card_no", bankCard.getSettle_acct());
		map.put("debit_card_name", bankCard.getAcct_nm());
		map.put("debit_card_phone", bankCard.getPhone());
		map.put("debit_card_idcard", bankCard.getCertificate_no());
		return map;
	}
	
	/**
	 * 组装图片上送业务应答参数
	 * @param imgId
	 * @return
	 */
	private Map<String, String> uploadResp(String imgId){
		Map<String, String> map = new HashMap<>();
		map.put("img_index", imgId);
		return map;
	}
	
}
